package org.aurora.remote;

import com.alibaba.fastjson.JSON;
import org.aurora.remote.protocol.RemoteRequest;
import org.aurora.remote.protocol.RemoteResponse;

import java.lang.reflect.ParameterizedType;
import java.nio.charset.StandardCharsets;

public abstract class AbstractRemoteProcessor<REQUEST extends RemoteRequest, RESPONSE extends RemoteResponse> implements RemoteProcessor<RemoteRequest, RemoteResponse> {
    @Override
    public RemoteResponse processor(RemoteRequest remoteRequest) {
        Class<REQUEST> requestClazz = (Class<REQUEST>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Class<RESPONSE> responseClazz = (Class<RESPONSE>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];

        REQUEST request = convertRequest(remoteRequest, requestClazz);
        RESPONSE response = doProcessor(request);

        return convertedResponse(remoteRequest, response);
    }

    public abstract RESPONSE doProcessor(REQUEST request);

    public RemoteResponse convertedResponse(RemoteRequest remoteRequest, RESPONSE response) {

        if (response == null) {
            response = (RESPONSE) new RemoteResponse();
        }

        response.setRequestOrdinal(remoteRequest.getRequestOrdinal());
        response.setSerializationType(remoteRequest.getSerializationType());

        return response;
    }

    public REQUEST convertRequest(RemoteRequest remoteRequest, Class<REQUEST> clazz) {
        byte[] data = remoteRequest.getData();

        String dataStr = new String(data, StandardCharsets.UTF_8);
        REQUEST request = JSON.parseObject(dataStr, clazz);

        request.setIp(remoteRequest.getIp());
        request.setPort(remoteRequest.getPort());

        return request;
    }
}
